1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::any::Any;
use std::pin::Pin;
use std::sync::Arc;

use crate::co;
use crate::decl::*;
use crate::gui::{*, privs::*};
use crate::prelude::*;
use crate::user::privs::*;

/// A
/// [message-only](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-features#message-only-windows)
/// window, which can handle events.
#[derive(Clone)]
pub struct WindowMessageOnly(Pin<Arc<RawBase>>);

unsafe impl Send for WindowMessageOnly {}

impl AsRef<Base> for WindowMessageOnly {
	fn as_ref(&self) -> &Base {
		self.0.base()
	}
}

impl GuiWindow for WindowMessageOnly {
	fn hwnd(&self) -> &HWND {
		self.0.base().hwnd()
	}

	fn as_any(&self) -> &dyn Any {
		self
	}
}

impl GuiParent for WindowMessageOnly {}

impl WindowMessageOnly {
	/// Instantiates a new `WindowMessageOnly` object, to be created internally
	/// with
	/// [`HWND::CreateWindowEx`](crate::prelude::user_Hwnd::CreateWindowEx).
	#[must_use]
	pub fn new(parent: Option<&WindowMessageOnly>) -> AnyResult<Self> {
		let new_self = Self(
			Arc::pin(RawBase::new(parent)),
		);
		new_self.create()?;
		Ok(new_self)
	}

	fn create(&self) -> AnyResult<()> {
		let hinst = HINSTANCE::GetModuleHandle(None)?;
		let mut wcx = WNDCLASSEX::default();
		let mut class_name_buf = WString::new();
		RawBase::fill_wndclassex(
			&hinst,
			co::CS::default(), &Icon::None, &Icon::None,
			&Brush::None, &Cursor::None, &mut wcx,
			&mut class_name_buf)?;
		let atom = self.0.register_class(&mut wcx)?;

		let hparent_msg = unsafe { HWND::from_ptr(HWND_MESSAGE as _) };

		self.0.create_window(
			Some(match self.0.base().parent() {
				Some(parent) => parent.hwnd(),
				None => &hparent_msg, // special case: message-only window with no parent
			}),
			atom, None, IdMenu::None,
			POINT::default(), SIZE::default(),
			co::WS_EX::NoValue, co::WS::NoValue,
		)?;

		Ok(())
	}
}